package com.example.mcp;

import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
 * 聊天MCP客户端测试 - 演示如何使用聊天MCP服务
 * <p>
 * 这个测试展示了聊天MCP服务的核心功能： 1. 获取聊天记录 2. 发送消息 3. 实时日志推送 4. 错误处理
 */
public class ChatMcpClientTest {

    private static final Logger logger = LoggerFactory.getLogger(ChatMcpClientTest.class);

    // 配置模拟器转发,把模拟器宿主机的ip端口映射的模拟器的8081端口上: adb forward tcp:8081 tcp:8081, 在宿主机上访问: http://localhost:8081 就可以连接到模拟器了
    private static final String SERVER_URL = "http://localhost:8081";
//    private static final String SERVER_URL = "http://192.168.0.104:8081";

    public static void main(String[] args) {
        logger.info("🚀 聊天MCP客户端测试 - 演示聊天服务功能");
        logger.info("==================================================");
        logger.info(SERVER_URL + "/sse");
        logger.info(SERVER_URL + "/message");

        try {
            // 1. 创建HTTP SSE传输层，确保使用UTF-8编码
            McpClientTransport transport = HttpClientSseClientTransport.builder(SERVER_URL)
                    .sseEndpoint("/sse")
                    .build();

            logger.info("📡 创建HTTP SSE传输层成功");

            // 2. 创建同步MCP客户端，配置各种消费者
            McpSyncClient client = McpClient.sync(transport)
                    .requestTimeout(Duration.ofSeconds(30))
                    .initializationTimeout(Duration.ofSeconds(5))
                    .capabilities(McpSchema.ClientCapabilities.builder().roots(true).sampling().build())
                    .clientInfo(new McpSchema.Implementation("chat-mcp-client", "1.0.0"))
                    .loggingConsumer(notification -> {
                        // 实时接收服务器推送的日志
                        logger.info("📝 [实时日志] [{}] {}: {}", notification.level(), notification.logger(),
                                notification.data());
                    })
                    .progressConsumer(notification -> {
                        // 实时接收进度更新
                        logger.info("📊 [进度更新] {}: {}/{} - {}", notification.progressToken(), notification.progress(),
                                notification.total(), notification.message());
                    })
                    .build();

            logger.info("🔧 创建聊天MCP客户端成功");

            // 3. 执行各种测试
//            runPingTest(client);
//            runGetAllConversationsTest(client);
//            runGetConversationByIdTest(client);
//            runGetMessagesByConversationIdTest(client);
            runSendMessageTest(client);
//            runErrorTest(client);

            logger.info("✅ 所有聊天服务测试完成");


        } catch (Exception e) {
            logger.error("❌ 测试失败", e);
        }
    }

    /**
     * 测试0: Ping/Pong连接检测功能
     */
    private static void runPingTest(McpSyncClient client) {
        logger.info("\n🧪 测试0: Ping/Pong连接检测");
        logger.info("----------------------------");
        logger.info("💡 演示如何检测服务器连接状态");

        try {
            // 调用ping工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("ping", Map.of());

            logger.info("🏓 发送ping请求...");
            logger.info("📝 注意观察实时日志推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ ping测试完成");
            logger.info("📄 ping响应: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ ping测试失败", e);
        }
    }

    /**
     * 测试1: 获取所有聊天记录功能
     */
    private static void runGetAllConversationsTest(McpSyncClient client) {
        logger.info("\n🧪 测试1: 获取所有聊天记录");
        logger.info("----------------------------");
        logger.info("💡 演示如何获取所有聊天记录列表");

        try {
            // 初始化客户端
            client.initialize();
            logger.info("✅ 客户端初始化成功");

            // 调用获取所有聊天记录的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_all_conversations", Map.of());

            logger.info("📋 调用获取所有聊天记录...");
            logger.info("📝 注意观察实时日志推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 获取聊天记录完成");
            logger.info("📄 聊天记录列表: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 获取聊天记录测试失败", e);
        }
    }

    /**
     * 测试2: 根据ID获取聊天记录功能
     */
    private static void runGetConversationByIdTest(McpSyncClient client) {
        logger.info("\n🧪 测试2: 根据ID获取聊天记录");
        logger.info("----------------------------");
        logger.info("💡 演示如何获取特定聊天记录的详细信息");

        try {
            // 调用根据ID获取聊天记录的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_conversation_by_id",
                    Map.of("conversation_id", "1"));

            logger.info("🔍 调用根据ID获取聊天记录...");
            logger.info("📝 注意观察实时日志推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 获取聊天记录详情完成");
            logger.info("📄 聊天记录详情: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 获取聊天记录详情测试失败", e);
        }
    }

    /**
     * 测试3: 根据会话ID获取消息列表功能
     */
    private static void runGetMessagesByConversationIdTest(McpSyncClient client) {
        logger.info("\n🧪 测试3: 根据会话ID获取消息列表");
        logger.info("----------------------------");
        logger.info("💡 演示如何获取指定会话的消息列表");

        try {
            // 调用根据会话ID获取消息列表的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_messages_by_conversation_id",
                    Map.of("conversation_id", "1"));

            logger.info("📋 调用根据会话ID获取消息列表...");
            logger.info("📝 注意观察实时日志推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 获取消息列表完成");
            logger.info("📄 消息列表: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 获取消息列表测试失败", e);
        }
    }

    /**
     * 测试4: 发送消息功能
     */
    private static void runSendMessageTest(McpSyncClient client) {
        logger.info("\n🧪 测试4: 发送消息");
        logger.info("----------------------------");
        logger.info("💡 演示如何发送消息到指定聊天记录");

        try {
            // 调用发送消息的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("send_message",
                    Map.of(
                            "conversation_id", "1",
                            "sender", "测试用户",
                            "content", "这是一条测试消息，通过MCP客户端发送！"
                    ));

            logger.info("📤 调用发送消息...");
            logger.info("📝 注意观察实时日志推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 发送消息完成");
            logger.info("📄 发送结果: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 发送消息测试失败", e);
        }
    }

    /**
     * 测试5: 错误处理功能
     */
    private static void runErrorTest(McpSyncClient client) {
        logger.info("\n🧪 测试5: 错误处理");
        logger.info("----------------------------");
        logger.info("💡 演示如何处理不存在的聊天记录ID");

        try {
            // 调用发送消息到不存在的聊天记录
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("send_message",
                    Map.of(
                            "conversation_id", "999", // 不存在的ID
                            "sender", "测试用户",
                            "content", "这条消息应该失败"
                    ));

            logger.info("📤 调用发送消息到不存在的聊天记录...");
            logger.info("📝 注意观察错误处理:");

            McpSchema.CallToolResult result = client.callTool(request);

            if (result.isError()) {
                logger.info("✅ 错误处理正确 - 成功捕获了错误");
                logger.info("📄 错误信息: {}", result.content());
            } else {
                logger.warn("⚠️ 预期应该返回错误，但返回了成功结果");
            }

        } catch (Exception e) {
            logger.error("❌ 错误处理测试失败", e);
        }
    }
}
